package statistics

import (
	"context"
	"sale-admin/internal/app/web/service/common"
	"sale-admin/internal/app/web/service/robot"
	"sale-admin/internal/dal"
	"sale-admin/internal/dao"
	"sale-admin/internal/define"
	"sale-admin/internal/models"
	"sort"
	"strconv"
	"strings"

	"github.com/golang-module/carbon/v2"
	"github.com/samber/lo"
	"gorm.io/gorm"
)

type CenterOrderService struct{}

// GetCenterOrder 订单流速
func (ss CenterOrderService) GetCenterOrder(ctx context.Context, db *gorm.DB, merchantID, Areas1, Areas2, Areas3, Areas5 string,
	Compare int, GoodsName, SalesID string, shopIDList []string, Type int, StartTime, EndTime string) (data interface{}, TotalCount TotalCountStruct, err error) {
	TotalCount = TotalCountStruct{}
	if Compare == 1 {
		if Type == define.HOUR {
			data, err = ss.getOrderCompareHour(ctx, db, merchantID, shopIDList, SalesID, Areas1, Areas2, Areas3, Areas5, StartTime, EndTime, GoodsName)
		} else if Type == define.DAY {
			data, err = ss.getOrderCompareDay(ctx, db, merchantID, shopIDList, SalesID, Areas1, Areas2, Areas3, Areas5, StartTime, EndTime, GoodsName)
		} else if Type == define.WEEK {
			data, err = ss.getOrderCompareWeek(ctx, db, merchantID, shopIDList, SalesID, Areas1, Areas2, Areas3, Areas5, StartTime, EndTime, GoodsName)
		} else if Type == define.MONTH {
			data, err = ss.getOrderCompareMonth(ctx, db, merchantID, shopIDList, SalesID, Areas1, Areas2, Areas3, Areas5, StartTime, EndTime, GoodsName)
		}
	} else {
		data, TotalCount, err = ss.GetCenterOrderNotCompare(ctx, db, merchantID, shopIDList, SalesID, Areas1, Areas2, Areas3, Areas5, StartTime, EndTime, GoodsName, Type)
	}
	return data, TotalCount, err
}

func (ss CenterOrderService) GetFaceCountMap(ctx context.Context, db *gorm.DB, merchantID, Areas3, StartTime, EndTime, salesID string,
	shopIDList []string, DateType int) (DateFaceCountMap map[string]dao.FaceCountList) {
	StartTime = carbon.Parse(StartTime).ToDateString()
	EndTime = carbon.Parse(EndTime).ToDateString()
	DateFaceCountMap = make(map[string]dao.FaceCountList)
	FaceCountList, _, _ := robot.FaceCount{}.GetFaceCount(ctx, db, merchantID, Areas3, StartTime, EndTime, salesID, shopIDList, DateType, false)
	for _, v := range FaceCountList {
		DateFaceCountMap[v.Date] = v
	}
	return DateFaceCountMap
}

type RefundStruct struct {
	Date              string  `json:"date"`
	RefundOrderCount  int     `json:"refund_order_count"`
	RefundOrderAmount float64 `json:"refund_order_amount"`
}

// 获取退款订单map
func (ss CenterOrderService) GetDateRefundOrderMap(ctx context.Context, db *gorm.DB, merchantID, areas1, areas2, areas3, areas5, StartTime, EndTime string, salesID string, shopIDList []string, dateFormat string) (dataMap map[string]RefundStruct) {
	var RefundList = []RefundStruct{}
	tx := db.Model(&models.MaOrder{}).
		Where("order_status = 6"). //退款
		Where("add_time between ? and ?", StartTime, EndTime)
	merchantIDList, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		return
	}

	if len(merchantIDList) > 0 {
		tx.Where("merchant_id in ?", merchantIDList)
	}

	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	field := "date_format(`add_time`, '" + dateFormat + "') as date,count(order_id) as refund_order_count,sum(payment_amount) as refund_order_amount"
	tx.Group("date_format(`add_time`, '" + dateFormat + "')").
		Select(field).
		Find(&RefundList)
	var DateRefundOrderMap = make(map[string]RefundStruct)
	for _, v := range RefundList {
		DateRefundOrderMap[v.Date] = RefundStruct{
			RefundOrderCount:  v.RefundOrderCount,
			RefundOrderAmount: v.RefundOrderAmount,
		}
	}
	return DateRefundOrderMap
}

type SuccessOrderStruct struct {
	Date              string  `json:"date"`
	SuccessOrderCount int     `json:"success_order_count"`
	PaymentAmount     float64 `json:"payment_amount"`
	DiscountAmount    float64 `json:"dis_count_amount"`
}
type DiscountOrderStruct struct {
	Date           string  `json:"date"`
	DiscountAmount float64 `json:"discount_amount"`
}

// 获取成功支付订单map
func (ss CenterOrderService) GetDateSuccessOrderMap(ctx context.Context, db *gorm.DB, merchantID, areas1, areas2, areas3, areas5, StartTime, EndTime string, salesID string, shopIDList []string, dateFormat string) (dataMap map[string]SuccessOrderStruct) {
	var SuccessList = []SuccessOrderStruct{}
	tx := db.Model(&models.MaOrder{}).
		Where("order_status = 4").
		Where("add_time between ? and ?", StartTime, EndTime)
	merchantIDList, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		return
	}
	if len(merchantIDList) > 0 {
		tx.Where("merchant_id in ?", merchantIDList)
	}
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}

	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	field := "date_format(`add_time`, '" + dateFormat + "') as date," +
		"count(order_id) as success_order_count," +
		"sum(payment_amount) as payment_amount," +
		"sum(discount_amount) as dis_count_amount"
	tx.
		Group("date_format(`add_time`, '" + dateFormat + "')").
		Select(field).
		Find(&SuccessList)

	var DateSuccessOrderMap = make(map[string]SuccessOrderStruct)
	for _, v := range SuccessList {
		DateSuccessOrderMap[v.Date] = SuccessOrderStruct{
			SuccessOrderCount: v.SuccessOrderCount,
			PaymentAmount:     v.PaymentAmount,
			DiscountAmount:    v.DiscountAmount,
		}
	}
	return DateSuccessOrderMap
}

// 获取成功支付订单map
func (ss CenterOrderService) GetDateDiscountOrderMap(ctx context.Context,
	db *gorm.DB, merchantID string, areas1, areas2, areas3, areas5,
	StartTime, EndTime string,
	salesID string,
	shopIDList []string,
	dateFormat string,
) (
	dataMap map[string]DiscountOrderStruct,
) {
	var data = []DiscountOrderStruct{}
	tx := db.Model(&models.MaOrder{}).
		Where("order_status = 4").
		Where("add_time between ? and ?", StartTime, EndTime)

	merchantIDList, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		return
	}
	if len(merchantIDList) > 0 {
		tx.Where("merchant_id in ?", merchantIDList)
	}

	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	tx.Group("date_format(`add_time`, '" + dateFormat + "')").
		Select(
			"date_format(`add_time`, '" + dateFormat + "') as date,sum(discount_amount) as discount_amount").
		Find(&data)

	var mymap = make(map[string]DiscountOrderStruct)
	for _, v := range data {
		var aa DiscountOrderStruct
		aa.DiscountAmount = v.DiscountAmount
		mymap[v.Date] = aa
	}
	return mymap
}

type ClickNumStruct struct {
	Date     string `json:"date"`
	ClickNum int    `json:"click_num"`
}

// 商品点击次数map
func (ss CenterOrderService) GetDateClickNumMap(ctx context.Context, db *gorm.DB, merchantID, areas1, areas2, areas3, areas5, StartTime, EndTime string, salesID string, shopIDList []string, dateFormat string) (dataMap map[string]ClickNumStruct) {
	var ClickNumList = []ClickNumStruct{}
	tx := db.Model(&models.MaGoodsClick{}).
		Where("start_time between ? and ?", StartTime, EndTime)
	merchantIDList, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		return
	}
	tx.Where("merchant_id in ?", merchantIDList)

	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	field := "date_format(`start_time`, '" + dateFormat + "') as date,sum(click_num) as click_num"
	tx.Group("date_format(`start_time`, '" + dateFormat + "')").
		Select(field).
		Find(&ClickNumList)
	var DateClickNumMap = make(map[string]ClickNumStruct)
	for _, v := range ClickNumList {
		DateClickNumMap[v.Date] = ClickNumStruct{
			ClickNum: v.ClickNum,
		}
	}
	return DateClickNumMap
}

type NotPayOrderStruct struct {
	Date             string `json:"date"`
	NotPayOrderCount int    `json:"not_pay_order_count"`
}

// 未支付订单map
func (ss CenterOrderService) GetNotPayOrderMap(ctx context.Context, db *gorm.DB, merchantID, areas1, areas2, areas3, areas5 string, StartTime, EndTime string, salesID string, shopIDList []string, dateFormat string) (dataMap map[string]NotPayOrderStruct) {
	var NotPayOrderList = []NotPayOrderStruct{}
	tx := db.Model(&models.MaOrder{}).
		Where("order_status IN (1, 3)").
		Where("add_time between ? and ?", StartTime, EndTime)
	merchantIDList, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		return
	}
	tx.Where("merchant_id in ?", merchantIDList)
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}

	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	field := "date_format(`add_time`, '" + dateFormat + "') as date,count(order_id) as not_pay_order_count"
	tx.Group("date_format(`add_time`, '" + dateFormat + "')").
		Select(field).
		Find(&NotPayOrderList)
	var DateNotPayOrderMap = make(map[string]NotPayOrderStruct)
	for _, v := range NotPayOrderList {
		DateNotPayOrderMap[v.Date] = NotPayOrderStruct{
			NotPayOrderCount: v.NotPayOrderCount,
		}
	}
	return DateNotPayOrderMap
}

type StartOrderStruct struct {
	Date            string `json:"date"`
	StartOrderCount int    `json:"start_order_count"`
}

// 已创建订单map
func (ss CenterOrderService) GetDateStartOrderMap(ctx context.Context, db *gorm.DB, merchantID, areas1, areas2, areas3, areas5 string, StartTime, EndTime string, salesID string, shopIDList []string, dateFormat string) (dataMap map[string]StartOrderStruct) {
	var StartOrderList = []StartOrderStruct{}
	tx := db.Model(&models.MaOrder{}).
		Where("order_status IN (1,3,4,5,6)").
		Where("add_time between ? and ?", StartTime, EndTime)
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	merchantIDList, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		return
	}
	tx.Where("merchant_id in ?", merchantIDList)

	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	field := "date_format(`add_time`, '" + dateFormat + "') as date,count(order_id) as start_order_count"
	tx.Group("date_format(`add_time`, '" + dateFormat + "')").
		Select(field).
		Find(&StartOrderList)
	var DateStartOrderMap = make(map[string]StartOrderStruct)
	for _, v := range StartOrderList {
		DateStartOrderMap[v.Date] = StartOrderStruct{
			StartOrderCount: v.StartOrderCount,
		}
	}
	return DateStartOrderMap
}

type PayNumStruct struct {
	Date   string `json:"date"`
	PayNum int64  `json:"pay_num"`
}

// 获取支付数量map
func (ss CenterOrderService) GetDatePayNumMap(ctx context.Context, db *gorm.DB, merchantID, StartTime, EndTime string, salesID string, shopIDList []string, dateFormat string) (dataMap map[string]PayNumStruct) {
	var PayNumList = []PayNumStruct{}
	tx := db.Model(&models.MaWechatRate{}).
		Where("add_time between ? and ?", StartTime, EndTime)
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	merchantIDList, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		return
	}
	tx.Where("id in ?", merchantIDList)
	field := "date_format(`add_time`, '" + dateFormat + "') as date,count(DISTINCT unique_id) as pay_num"
	tx.Group("date_format(`add_time`, '" + dateFormat + "')").
		Select(field).
		Find(&PayNumList)
	var DatePayNumMap = make(map[string]PayNumStruct)
	for _, v := range PayNumList {
		DatePayNumMap[v.Date] = PayNumStruct{
			PayNum: v.PayNum,
		}
	}
	return DatePayNumMap
}

// 周起止时间
func SortWeekDays(WeekDays struct {
	Max string
	Min string
}, day string) (data struct {
	Max string
	Min string
}) {
	if WeekDays.Min == "" || WeekDays.Min > day {
		WeekDays.Min = day
	}
	if WeekDays.Max == "" || WeekDays.Max < day {
		WeekDays.Max = day
	}
	return WeekDays
}

type CenterOrderCompareStruct struct {
	Date               string  `json:"date"`
	Hour               int     `json:"hour"`
	GMV                float64 `json:"gmv"`
	YearWeek           int     `gorm:"-" json:"-"`
	DayCountNum        int     `json:"day_count_num"`
	DayPayNum          int     `json:"day_pay_num"`
	DayPayAmount       float64 `json:"day_pay_amount"`
	DisCount           int64   `json:"dis_count"`
	GoodsMoney         float64 `json:"goods_money"`
	DisCountAmount     float64 `json:"dis_count_amount"`
	StartOrderCount    int     `gorm:"-" json:"start_order_count"`
	PaymentAmount      float64 `gorm:"-" json:"payment_amount"`
	SuccessOrderCount  int     `gorm:"-" json:"success_order_count"`
	SuccessOrderAmount float64 `gorm:"-" json:"success_order_amount"`
	RefundOrderCount   int     `gorm:"-" json:"refund_order_count"`
	RefundOrderAmount  float64 `gorm:"-" json:"refund_order_amount"`
	NotPayOrderCount   int     `gorm:"-" json:"not_pay_order_count"`
	FaceCount          float64 `gorm:"-" json:"facecount"`
	FaceCount0         float64 `gorm:"-" json:"facecount0"`
	FaceCount1         float64 `gorm:"-" json:"facecount1"`
	FaceCount2         float64 `gorm:"-" json:"facecount2"`
	FaceCount3         float64 `gorm:"-" json:"facecount3"`
	ClickNum           int     `gorm:"-" json:"click_num"`
}

// 订单对比 -- 按时
func (ss CenterOrderService) getOrderCompareHour(ctx context.Context, db *gorm.DB, merchantID string, shopIDList []string,
	salesID, areas1, areas2, areas3, areas5, StartTime, EndTime, GoodsName string) (data []CenterOrderCompareStruct, err error) {
	//时间筛选
	common.HandlerTime(&StartTime, &EndTime, define.HOUR)
	tx := db.Model(&models.MaOrder{}).
		Where("order_status in (1,3,4,5,6)").
		Where("add_time between ? and ?", StartTime, EndTime)
	//商户
	merchantIDs, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		err = err1
		return
	}
	tx.Where("merchant_id in (?)", merchantIDs)

	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	if GoodsName != "" {
		unicodeName, _ := common.UnicodeEncode(GoodsName)
		tx.Where("count_data like '%" + strings.ReplaceAll(unicodeName, "\\", "_") + "%'")
	}

	field := "date_format(add_time, '%Y-%m-%d') AS date," +
		"date_format(add_time, '%H') as hour," +
		"ifnull(sum(payment_amount),0) as gmv," +
		"( SELECT 0 ) dis_count," +
		"( SELECT 0 ) goods_money"
	var Result = []CenterOrderCompareStruct{}
	tx.WithContext(ctx).Select(field).Find(&Result)

	dateType := define.HOUR
	//人脸数据
	DateFaceCountMap := ss.GetFaceCountMap(ctx, db, merchantID, areas3, StartTime, EndTime, salesID, shopIDList, dateType)
	//商品点击次数
	DateClickNumMap := ss.GetDateClickNumMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d %H")
	//退款订单
	DateRefundOrderMap := ss.GetDateRefundOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d %H")
	//成功支付
	DateSuccessOrderMap := ss.GetDateSuccessOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d %H")
	//未支付订单
	DateNotPayOrderMap := ss.GetNotPayOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d %H")
	//已创建订单
	DateStartOrderMap := ss.GetDateStartOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d %H")

	var ResultDateMap = make(map[string][]CenterOrderCompareStruct) //日期 => 结果数组
	for k, v := range Result {
		dateHour := v.Date + " " + strconv.Itoa(v.Hour) + ":00"
		if _, ok := DateRefundOrderMap[dateHour]; ok {
			Result[k].RefundOrderAmount = DateRefundOrderMap[dateHour].RefundOrderAmount
			Result[k].RefundOrderCount = DateRefundOrderMap[dateHour].RefundOrderCount
		}
		if _, ok := DateSuccessOrderMap[dateHour]; ok {
			Result[k].PaymentAmount = DateSuccessOrderMap[dateHour].PaymentAmount
			Result[k].SuccessOrderCount = DateSuccessOrderMap[dateHour].SuccessOrderCount
			Result[k].DisCountAmount = DateSuccessOrderMap[dateHour].DiscountAmount
		}
		if _, ok := DateStartOrderMap[dateHour]; ok {
			Result[k].StartOrderCount = DateStartOrderMap[dateHour].StartOrderCount
		}
		if _, ok := DateNotPayOrderMap[dateHour]; ok {
			Result[k].NotPayOrderCount = DateNotPayOrderMap[dateHour].NotPayOrderCount
		}
		if _, ok := DateFaceCountMap[dateHour]; ok {
			Result[k].FaceCount = DateFaceCountMap[dateHour].FaceCount
			Result[k].FaceCount0 = DateFaceCountMap[dateHour].FaceCount0
			Result[k].FaceCount1 = DateFaceCountMap[dateHour].FaceCount1
			Result[k].FaceCount2 = DateFaceCountMap[dateHour].FaceCount2
			Result[k].FaceCount3 = DateFaceCountMap[dateHour].FaceCount3
		}
		if _, ok := DateClickNumMap[dateHour]; ok {
			Result[k].ClickNum = DateClickNumMap[dateHour].ClickNum
		}
		ResultDateMap[v.Date] = append(ResultDateMap[v.Date], Result[k])
	}

	//填充时间数组
	FullTimeList := common.GetHourPeriods(StartTime, EndTime) //2006-01-02 15:00
	//填充完整数据 年月日时 =》数据
	var FullDateHourResultMap = make(map[string][]CenterOrderCompareStruct)
	for _, v := range FullTimeList {
		date := carbon.Parse(v).ToDateString()
		hour := strings.TrimPrefix(v[11:13], "0")
		var item CenterOrderCompareStruct
		if _, ok := ResultDateMap[date]; ok {
			for _, res := range ResultDateMap[date] {
				if strconv.Itoa(res.Hour) == hour {
					item = res
				}
			}
		} else {
			item.Hour, _ = strconv.Atoi(hour)
		}
		FullDateHourResultMap[date] = append(FullDateHourResultMap[date], item)
	}
	var ReturnData = []CenterOrderCompareStruct{}
	for date, ResList := range FullDateHourResultMap {
		var NewEmpty24Data []CenterOrderCompareStruct
		for i := 0; i < 24; i++ {
			var item CenterOrderCompareStruct
			item.Hour = i
			item.Date = date
			NewEmpty24Data = append(NewEmpty24Data, item)
		}
		for _, res := range ResList {
			for k, v := range NewEmpty24Data {
				if v.Hour == res.Hour {
					NewEmpty24Data[k].GMV = res.GMV
					NewEmpty24Data[k].GoodsMoney = res.GoodsMoney
					NewEmpty24Data[k].DisCount = res.DisCount
					NewEmpty24Data[k].StartOrderCount = res.StartOrderCount
					NewEmpty24Data[k].PaymentAmount = res.PaymentAmount
					NewEmpty24Data[k].RefundOrderAmount = res.RefundOrderAmount
					NewEmpty24Data[k].RefundOrderCount = res.RefundOrderCount
					NewEmpty24Data[k].FaceCount = res.FaceCount
					NewEmpty24Data[k].FaceCount0 = res.FaceCount0
					NewEmpty24Data[k].FaceCount1 = res.FaceCount1
					NewEmpty24Data[k].FaceCount2 = res.FaceCount2
					NewEmpty24Data[k].FaceCount3 = res.FaceCount3
					NewEmpty24Data[k].ClickNum = res.ClickNum
					NewEmpty24Data[k].SuccessOrderCount = res.SuccessOrderCount
					NewEmpty24Data[k].NotPayOrderCount = res.NotPayOrderCount
				}
			}
		}
		ReturnData = append(ReturnData, NewEmpty24Data...)
	}
	sort.Slice(ReturnData, func(i, j int) bool {
		if ReturnData[i].Date == ReturnData[j].Date {
			return ReturnData[i].Hour < ReturnData[j].Hour
		} else {
			return ReturnData[i].Date < ReturnData[j].Date
		}
	})
	return ReturnData, nil
}

// 订单对比 -- 按天
func (ss CenterOrderService) getOrderCompareDay(ctx context.Context, db *gorm.DB, merchantID string, shopIDList []string,
	salesID, areas1, areas2, areas3, areas5, StartTime, EndTime, GoodsName string) (data []CenterOrderCompareStruct, err error) {
	common.HandlerTime(&StartTime, &EndTime, define.DAY)
	tx := db.Model(&models.MaOrder{}).
		Where("order_status in (1,3,4,5,6)").
		Where("add_time between ? and ?", StartTime, EndTime)
		//商户
	merchantIDs, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		err = err1
		return
	}
	tx.Where("merchant_id in (?)", merchantIDs)
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	if GoodsName != "" {
		unicodeName, _ := common.UnicodeEncode(GoodsName)
		tx.Where("count_data like '%" + strings.ReplaceAll(unicodeName, "\\", "_") + "%'")
	}
	var Result = []CenterOrderCompareStruct{}
	var field string
	if len(shopIDList) == 1 && shopIDList[0] == "1" { //系统管理员
		field = "date_format(`add_time`, '%Y-%m-%d') AS date," +
			"sum(payment_amount) AS gmv," +
			"( SELECT 0) dis_count," +
			"( SELECT 0) goods_money"
	} else {
		field = "date_format(`add_time`, '%Y-%m-%d') AS date," +
			"sum(payment_amount) as gmv," +
			"SUM(payment_amount) AS day_pay_amount," +
			"COUNT(order_id) AS day_pay_num," +
			"(select 0) AS dis_count_amount"
	}
	tx.Group("date_format(`add_time`, '%Y-%m-%d')").
		Order("add_time asc").
		Select(field).
		Find(&Result)

	dateType := define.DAY
	//人脸数据
	DateFaceCountMap := ss.GetFaceCountMap(ctx, db, merchantID, areas3, StartTime, EndTime, salesID, shopIDList, dateType)
	//商品点击次数
	DateClickNumMap := ss.GetDateClickNumMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	//退款订单
	DateRefundOrderMap := ss.GetDateRefundOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	//成功支付
	DateSuccessOrderMap := ss.GetDateSuccessOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	//未支付订单
	DateNotPayOrderMap := ss.GetNotPayOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	//已创建订单
	DateStartOrderMap := ss.GetDateStartOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	for k, v := range Result {
		if _, ok := DateRefundOrderMap[v.Date]; ok {
			Result[k].RefundOrderAmount = DateRefundOrderMap[v.Date].RefundOrderAmount
			Result[k].RefundOrderCount = DateRefundOrderMap[v.Date].RefundOrderCount
		}
		if _, ok := DateSuccessOrderMap[v.Date]; ok {
			Result[k].PaymentAmount = DateSuccessOrderMap[v.Date].PaymentAmount
			Result[k].SuccessOrderCount = DateSuccessOrderMap[v.Date].SuccessOrderCount
		}
		if _, ok := DateStartOrderMap[v.Date]; ok {
			Result[k].StartOrderCount = DateStartOrderMap[v.Date].StartOrderCount
		}
		if _, ok := DateNotPayOrderMap[v.Date]; ok {
			Result[k].NotPayOrderCount = DateNotPayOrderMap[v.Date].NotPayOrderCount
		}
		if _, ok := DateFaceCountMap[v.Date]; ok {
			Result[k].FaceCount = DateFaceCountMap[v.Date].FaceCount
			Result[k].FaceCount0 = DateFaceCountMap[v.Date].FaceCount0
			Result[k].FaceCount1 = DateFaceCountMap[v.Date].FaceCount1
			Result[k].FaceCount2 = DateFaceCountMap[v.Date].FaceCount2
			Result[k].FaceCount3 = DateFaceCountMap[v.Date].FaceCount3
		}
		if _, ok := DateClickNumMap[v.Date]; ok {
			Result[k].ClickNum = DateClickNumMap[v.Date].ClickNum
		}
	}

	var DateResult = []CenterOrderCompareStruct{} //日期 => 结果数组
	for date, faceCount := range DateFaceCountMap {
		var item CenterOrderCompareStruct
		item.Date = date
		item.FaceCount = faceCount.FaceCount
		item.FaceCount0 = faceCount.FaceCount0
		item.FaceCount1 = faceCount.FaceCount1
		item.FaceCount2 = faceCount.FaceCount2
		item.FaceCount3 = faceCount.FaceCount3
		for _, res := range Result {
			if res.Date == date {
				item.GMV = res.GMV
				item.DisCount = res.DisCount
				item.GoodsMoney = res.GoodsMoney
				item.DayPayAmount = res.DayPayAmount
				item.DayPayNum = res.DayPayNum
				item.DisCountAmount = res.DisCountAmount
				item.StartOrderCount = res.StartOrderCount
				item.PaymentAmount = res.PaymentAmount
				item.SuccessOrderCount = res.SuccessOrderCount
				item.SuccessOrderAmount = res.SuccessOrderAmount
				item.RefundOrderCount = res.RefundOrderCount
				item.RefundOrderAmount = res.RefundOrderAmount
				item.NotPayOrderCount = res.NotPayOrderCount
				item.FaceCount = res.FaceCount
				item.FaceCount0 = res.FaceCount0
				item.FaceCount1 = res.FaceCount1
				item.FaceCount2 = res.FaceCount2
				item.FaceCount3 = res.FaceCount3
				item.ClickNum = res.ClickNum
			}
		}
		DateResult = append(DateResult, item)
	}
	sort.Slice(DateResult, func(i, j int) bool {
		return DateResult[i].Date < DateResult[j].Date
	})
	return DateResult, nil
}

// 订单对比 -- 按周
func (ss CenterOrderService) getOrderCompareWeek(ctx context.Context, db *gorm.DB, merchantID string, shopIDList []string,
	salesID, areas1, areas2, areas3, areas5, StartTime, EndTime, GoodsName string) (data []CenterOrderCompareStruct, err error) {
	//时间筛选
	common.HandlerTime(&StartTime, &EndTime, define.WEEK)
	tx := db.Model(&models.MaOrder{}).
		Where("order_status in (1,3,4,5,6)").
		Where("add_time between ? and ?", StartTime, EndTime)
	//商户
	merchantIDs, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		err = err1
		return
	}
	tx.Where("merchant_id in (?)", merchantIDs)

	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	if GoodsName != "" {
		unicodeName, _ := common.UnicodeEncode(GoodsName)
		tx.Where("count_data like '%" + strings.ReplaceAll(unicodeName, "\\", "_") + "%'")
	}
	var Result = []CenterOrderCompareStruct{}
	var field = "COUNT(order_id) as day_count_num," +
		"date_format(add_time, '%Y-%m-%d') AS date," +
		"COUNT(order_id) as day_pay_num," +
		"SUM(payment_amount) as day_pay_amount," +
		"sum(payment_amount) as gmv," +
		"(SELECT 0 ) as dis_count," +
		"(SELECT 0 ) as goods_money"
	tx.Group("date_format(`add_time`, '%Y-%m-%d')").
		Order("add_time asc").
		Select(field).
		Find(&Result)

	dateType := define.DAY //周按日计算
	//人脸数据
	DateFaceCountMap := ss.GetFaceCountMap(ctx, db, merchantID, areas3, StartTime, EndTime, salesID, shopIDList, dateType)
	//商品点击次数
	DateClickNumMap := ss.GetDateClickNumMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	//退款订单
	DateRefundOrderMap := ss.GetDateRefundOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	//成功支付
	DateSuccessOrderMap := ss.GetDateSuccessOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	//未支付订单
	DateNotPayOrderMap := ss.GetNotPayOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")
	//已创建订单
	DateStartOrderMap := ss.GetDateStartOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m-%d")

	for k, v := range Result {
		if _, ok := DateRefundOrderMap[v.Date]; ok {
			Result[k].RefundOrderAmount = DateRefundOrderMap[v.Date].RefundOrderAmount
			Result[k].RefundOrderCount = DateRefundOrderMap[v.Date].RefundOrderCount
		}
		if _, ok := DateSuccessOrderMap[v.Date]; ok {
			Result[k].PaymentAmount = DateSuccessOrderMap[v.Date].PaymentAmount
			Result[k].SuccessOrderCount = DateSuccessOrderMap[v.Date].SuccessOrderCount
		}
		if _, ok := DateStartOrderMap[v.Date]; ok {
			Result[k].StartOrderCount = DateStartOrderMap[v.Date].StartOrderCount
		}
		if _, ok := DateNotPayOrderMap[v.Date]; ok {
			Result[k].NotPayOrderCount = DateNotPayOrderMap[v.Date].NotPayOrderCount
		}
		if _, ok := DateFaceCountMap[v.Date]; ok {
			Result[k].FaceCount = DateFaceCountMap[v.Date].FaceCount
			Result[k].FaceCount0 = DateFaceCountMap[v.Date].FaceCount0
			Result[k].FaceCount1 = DateFaceCountMap[v.Date].FaceCount1
			Result[k].FaceCount2 = DateFaceCountMap[v.Date].FaceCount2
			Result[k].FaceCount3 = DateFaceCountMap[v.Date].FaceCount3
		}
		if _, ok := DateClickNumMap[v.Date]; ok {
			Result[k].ClickNum = DateClickNumMap[v.Date].ClickNum
		}
		Result[k].YearWeek = common.GetWeekOfYearInt(v.Date)
	}

	FullTimeList := common.GetPeriodsByType(StartTime, EndTime, define.WEEK)
	//填补空值
	var FullTimeResult = []CenterOrderCompareStruct{}
	var YearWeekDaysMap = make(map[int]struct {
		Max string
		Min string
	})
	for _, v := range FullTimeList {
		var dateRes = CenterOrderCompareStruct{}
		dateRes.Date = v
		for _, res := range Result {
			if v == res.Date {
				dateRes = res
				break
			}
		}
		dateRes.YearWeek = common.GetWeekOfYearInt(v)
		YearWeekDaysMap[dateRes.YearWeek] = SortWeekDays(YearWeekDaysMap[dateRes.YearWeek], v)
		FullTimeResult = append(FullTimeResult, dateRes)
	}

	//周 => 数据统计
	var WeekResultMap = make(map[int]CenterOrderCompareStruct)
	for _, v := range FullTimeResult {
		var item CenterOrderCompareStruct
		if _, ok := WeekResultMap[v.YearWeek]; ok {
			item = WeekResultMap[v.YearWeek]
		}
		item.Date = YearWeekDaysMap[v.YearWeek].Min + "/" + YearWeekDaysMap[v.YearWeek].Max
		item.YearWeek = v.YearWeek
		item.GMV += common.Decimal(v.GMV, 4)
		item.DisCount += v.DisCount
		item.GoodsMoney += v.GoodsMoney
		item.DisCountAmount += common.Decimal(v.DisCountAmount, 4)
		item.StartOrderCount += v.StartOrderCount
		item.PaymentAmount += common.Decimal(v.PaymentAmount, 4)
		item.SuccessOrderCount += v.SuccessOrderCount
		item.SuccessOrderAmount += common.Decimal(v.SuccessOrderAmount, 4)
		item.RefundOrderCount += v.RefundOrderCount
		item.RefundOrderAmount += common.Decimal(v.RefundOrderAmount, 4)
		item.NotPayOrderCount += v.NotPayOrderCount
		item.FaceCount += v.FaceCount
		item.FaceCount0 += v.FaceCount0
		item.FaceCount1 += v.FaceCount1
		item.FaceCount2 += v.FaceCount2
		item.FaceCount3 += v.FaceCount3
		item.ClickNum += v.ClickNum
		WeekResultMap[v.YearWeek] = item
	}
	data = lo.MapToSlice(WeekResultMap, func(k int, v CenterOrderCompareStruct) CenterOrderCompareStruct {
		return v
	})
	sort.Slice(data, func(i, j int) bool {
		return data[i].YearWeek < data[j].YearWeek
	})
	return
}

// 订单对比 -- 按月
func (ss CenterOrderService) getOrderCompareMonth(ctx context.Context, db *gorm.DB, merchantID string, shopIDList []string,
	salesID, areas1, areas2, areas3, areas5, StartTime, EndTime, GoodsName string) (data []CenterOrderCompareStruct, err error) {
	common.HandlerTime(&StartTime, &EndTime, define.MONTH)
	tx := db.Model(&models.MaOrder{}).
		Where("order_status in (1,3,4,5,6)").
		Where("add_time between ? and ?", StartTime, EndTime)
	//商户
	merchantIDs, err1 := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err1 != nil {
		err = err1
		return
	}
	tx.Where("merchant_id in (?)", merchantIDs)
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
	}
	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
	}
	if GoodsName != "" {
		unicodeName, _ := common.UnicodeEncode(GoodsName)
		tx.Where("count_data like '%" + strings.ReplaceAll(unicodeName, "\\", "_") + "%'")
	}
	var Result = []CenterOrderCompareStruct{}
	var field = "COUNT(order_id) as day_count_num," +
		"date_format(add_time, '%Y-%m') AS date," +
		"COUNT(order_id) as day_pay_num," +
		"SUM(payment_amount) as day_pay_amount," +
		"sum(payment_amount) as gmv," +
		"(SELECT 0 ) as dis_count," +
		"(SELECT 0 ) as goods_money"
	tx.Group("date_format(`add_time`, '%Y-%m')").
		Order("add_time asc").
		Select(field).
		Find(&Result)

	dateType := define.MONTH
	//人脸数据
	DateFaceCountMap := ss.GetFaceCountMap(ctx, db, merchantID, areas3, StartTime, EndTime, salesID, shopIDList, dateType)
	//商品点击次数
	DateClickNumMap := ss.GetDateClickNumMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m")
	//退款订单
	DateRefundOrderMap := ss.GetDateRefundOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m")
	//成功支付
	DateSuccessOrderMap := ss.GetDateSuccessOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m")
	//未支付订单
	DateNotPayOrderMap := ss.GetNotPayOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m")
	//已创建订单
	DateStartOrderMap := ss.GetDateStartOrderMap(ctx, db, merchantID, areas1, areas2, areas3, "", StartTime, EndTime, salesID, shopIDList, "%Y-%m")

	for k, v := range Result {
		if _, ok := DateRefundOrderMap[v.Date]; ok {
			Result[k].RefundOrderAmount = DateRefundOrderMap[v.Date].RefundOrderAmount
			Result[k].RefundOrderCount = DateRefundOrderMap[v.Date].RefundOrderCount
		}
		if _, ok := DateSuccessOrderMap[v.Date]; ok {
			Result[k].PaymentAmount = DateSuccessOrderMap[v.Date].PaymentAmount
			Result[k].SuccessOrderCount = DateSuccessOrderMap[v.Date].SuccessOrderCount
		}
		if _, ok := DateStartOrderMap[v.Date]; ok {
			Result[k].StartOrderCount = DateStartOrderMap[v.Date].StartOrderCount
		}
		if _, ok := DateNotPayOrderMap[v.Date]; ok {
			Result[k].NotPayOrderCount = DateNotPayOrderMap[v.Date].NotPayOrderCount
		}
		if _, ok := DateFaceCountMap[v.Date]; ok {
			Result[k].FaceCount = DateFaceCountMap[v.Date].FaceCount
			Result[k].FaceCount0 = DateFaceCountMap[v.Date].FaceCount0
			Result[k].FaceCount1 = DateFaceCountMap[v.Date].FaceCount1
			Result[k].FaceCount2 = DateFaceCountMap[v.Date].FaceCount2
			Result[k].FaceCount3 = DateFaceCountMap[v.Date].FaceCount3
		}
		if _, ok := DateClickNumMap[v.Date]; ok {
			Result[k].ClickNum = DateClickNumMap[v.Date].ClickNum
		}
	}
	//填充时间
	FullTimeList := common.GetPeriodsByType(StartTime, EndTime, define.MONTH)
	var FullTimeResult = []CenterOrderCompareStruct{}
	for _, v := range FullTimeList {
		var dateRes = CenterOrderCompareStruct{}
		for _, res := range Result {
			if v == res.Date {
				dateRes = res
				break
			}
		}
		dateRes.Date = v
		FullTimeResult = append(FullTimeResult, dateRes)
	}
	return FullTimeResult, nil
}

type CenterOrderStruct struct {
	Date               string  `json:"date"`
	Week               string  `json:"week"`
	DayCountNum        int     `json:"day_count_num"`
	DayPayNum          int     `json:"day_pay_num"`
	DayPayAmount       float64 `json:"day_pay_amount"`
	DisCountAmount     float64 `json:"dis_count_amount"`
	SuccessOrderCount  int     `gorm:"-" json:"success_order_count"`
	SuccessOrderAmount float64 `gorm:"-" json:"success_order_amount"`
	RefundOrderCount   int     `gorm:"-" json:"refund_order_count"`
	RefundOrderAmount  float64 `gorm:"-" json:"refund_order_amount"`
	NotPayOrderCount   int     `gorm:"-" json:"not_pay_order_count"`
	FaceCount          float64 `gorm:"-" json:"face_count"`
	FaceCount0         float64 `gorm:"-" json:"face_count0"`
	FaceCount1         float64 `gorm:"-" json:"face_count1"`
	FaceCount2         float64 `gorm:"-" json:"face_count2"`
	FaceCount3         float64 `gorm:"-" json:"face_count3"`
	PayNum             int64   `gorm:"-" json:"pay_num"`
	ClickNum           int     `gorm:"-" json:"click_num"`
	YearWeek           int     `gorm:"-" json:"year_week"`
}

type TotalCountStruct struct {
	DayCountNum             int     `json:"day_count_num"`
	DayPayNum               int     `json:"day_pay_num"`
	DayPayAmount            float64 `json:"day_pay_amount"`
	TotalPayNum             int     `json:"total_pay_num"`
	TotalDisCountAmount     float64 `json:"total_dis_count_amount"`
	TotalSuccessOrderCount  int     `json:"total_success_order_count"`
	TotalSuccessOrderAmount float64 `json:"total_success_order_amount"`
	TotalNotPayOrderCount   int     `json:"total_not_pay_order_count"`
	TotalRefundOrderCount   int     `json:"total_refund_order_count"`
	TotalRefundOrderAmount  float64 `json:"total_refund_order_amount"`
	TotalFaceCount          float64 `json:"total_face_count"`
	TotalClickNum           int     `json:"total_click_num"`
}

// 订单流速
func (ss CenterOrderService) GetCenterOrderNotCompare(
	ctx context.Context,
	db *gorm.DB,
	merchantID string,
	shopIDList []string,
	salesID, areas1, areas2, areas3, areas5,
	StartTime, EndTime,
	GoodsName string,
	dateType int,
) (
	data []CenterOrderStruct,
	TotalCount TotalCountStruct,
	err error,
) {
	DateFormateMap := map[int]string{
		define.HOUR:  "%Y-%m-%d %H:00",
		define.DAY:   "%Y-%m-%d",
		define.WEEK:  "%Y-%m-%d",
		define.MONTH: "%Y-%m",
		define.YEAR:  "%Y",
	}
	DateFormate := DateFormateMap[dateType]
	common.HandlerTime(&StartTime, &EndTime, dateType)
	tx := db.Model(&models.MaOrder{}).
		Where("order_status in (1,3,4,5,6)").
		Where("add_time between ? AND ?", StartTime, EndTime)
	var TotalWhere = " AND date_format(o2.add_time, '" + DateFormate + "') = date_format(add_time, '" + DateFormate + "') AND add_time between '" + StartTime + "' AND '" + EndTime + "'"
	var GoodsWhere = " start_time between '" + StartTime + "' AND '" + EndTime + "'"
	//商户
	merchantIDList, err := common.Order{}.GetMerchantChildren(ctx, merchantID, shopIDList)
	if err != nil {
		return
	}
	tx.Where("merchant_id in (?)", merchantIDList)
	if len(merchantIDList) > 0 {
		var merchantString string
		for _, v := range merchantIDList {
			merchantString += " \"" + v + "\","
		}
		merchantString = strings.TrimSuffix(merchantString, ",")
		TotalWhere += " AND o2.merchant_id in (" + merchantString + ")"
		GoodsWhere += " AND merchant_id in (" + merchantString + ")"
	}
	if salesID != "" {
		tx.Where("sales_id in (?)", strings.Split(salesID, ","))
		var salesIDList string
		for _, v := range strings.Split(salesID, ",") {
			salesIDList += "\"" + v + "\","
		}
		salesIDList = strings.TrimSuffix(salesIDList, ",")
		TotalWhere += " AND o2.sales_id in (" + salesIDList + ")"
		GoodsWhere += " AND sales_id in (" + salesIDList + ")"
	}
	if areas1 != "" {
		tx.Where("areas1 in (?)", strings.Split(areas1, ","))
		TotalWhere += " AND o2.areas1 in (" + areas1 + ")"
	}
	if areas2 != "" {
		tx.Where("areas2 in (?)", strings.Split(areas2, ","))
		TotalWhere += " AND o2.areas2 in (" + areas2 + ")"
	}
	if areas3 != "" {
		tx.Where("areas3 in (?)", strings.Split(areas3, ","))
		TotalWhere += " AND o2.areas3 in (" + areas3 + ")"
	}
	if areas5 != "" {
		tx.Where("areas5 in (?)", strings.Split(areas5, ","))
		TotalWhere += " AND o2.areas5 in (" + areas5 + ")"
	}
	if GoodsName != "" {
		unicodeName, _ := common.UnicodeEncode(GoodsName)
		tx.Where("count_data like '%" + strings.ReplaceAll(unicodeName, "\\", "_") + "%'")
		TotalWhere += " AND o2.count_data like '%" + strings.ReplaceAll(unicodeName, "\\", "_") + "%'"
	}

	//人脸数据
	DateFaceCountMap := ss.GetFaceCountMap(ctx, db, merchantID, areas3, StartTime, EndTime, salesID, shopIDList, dateType)
	//商品点击次数
	DateClickNumMap := ss.GetDateClickNumMap(ctx, db, merchantID, areas1, areas2, areas3, areas5, StartTime, EndTime, salesID, shopIDList, DateFormate)
	//退款订单
	DateRefundOrderMap := ss.GetDateRefundOrderMap(ctx, db, merchantID, areas1, areas2, areas3, areas5, StartTime, EndTime, salesID, shopIDList, DateFormate)
	//成功支付
	DateSuccessOrderMap := ss.GetDateSuccessOrderMap(ctx, db, merchantID, areas1, areas2, areas3, areas5, StartTime, EndTime, salesID, shopIDList, DateFormate)
	//优惠金额
	DateDiscountOrderMap := ss.GetDateDiscountOrderMap(ctx, db, merchantID, areas1, areas2, areas3, areas5, StartTime, EndTime, salesID, shopIDList, DateFormate)
	//未支付订单
	DateNotPayOrderMap := ss.GetNotPayOrderMap(ctx, db, merchantID, areas1, areas2, areas3, areas5, StartTime, EndTime, salesID, shopIDList, DateFormate)

	//支付数量
	DatePayNumMap := ss.GetDatePayNumMap(ctx, db, merchantID, StartTime, EndTime, salesID, shopIDList, DateFormate)
	Result := []CenterOrderStruct{}
	TotalCount = TotalCountStruct{}
	field1 := "COUNT(order_id) AS day_count_num, COUNT(order_id) AS day_pay_num, SUM(payment_amount) AS day_pay_amount"
	tx.WithContext(ctx).Select(field1).Take(&TotalCount)

	var successOrderStruct struct {
		TotalDisCountAmount     float64 `json:"total_dis_count_amount"`
		TotalSuccessOrderCount  int     `json:"total_success_order_count"`
		TotalSuccessOrderAmount float64 `json:"total_success_order_amount"`
	}
	db.Table(models.MaOrder{}.TableName()+" as o2").
		Where("order_status = 4 "+TotalWhere).
		Select(
			"count(order_id) as total_success_order_count",
			"sum(payment_amount) as total_success_order_amount",
			"sum(discount_amount) as total_dis_count_amount",
		).
		Take(&successOrderStruct)
	TotalCount.TotalSuccessOrderCount = successOrderStruct.TotalSuccessOrderCount
	TotalCount.TotalSuccessOrderAmount = successOrderStruct.TotalSuccessOrderAmount
	TotalCount.TotalDisCountAmount = successOrderStruct.TotalDisCountAmount

	db.Table(models.MaOrder{}.TableName() + " as o2").Where("order_status IN(1,3) " + TotalWhere).Select("count(order_id) as total_not_pay_order_count").Take(&TotalCount.TotalNotPayOrderCount)
	var refundOrderStruct struct {
		TotalRefundOrderCount  int     `json:"total_refund_order_count"`
		TotalRefundOrderAmount float64 `json:"total_refund_order_amount"`
	}
	db.Table(models.MaOrder{}.TableName()+" as o2").
		Where("order_status = 6 "+TotalWhere).
		Select("count(order_id) as total_refund_order_count", "sum(payment_amount) as total_refund_order_amount").
		Take(&refundOrderStruct)
	TotalCount.TotalRefundOrderCount = refundOrderStruct.TotalRefundOrderCount
	TotalCount.TotalRefundOrderAmount = refundOrderStruct.TotalRefundOrderAmount

	db.Model(&models.MaGoodsClick{}).Where(GoodsWhere).Select("ifnull(sum(click_num),0) as total_click_num").Take(&TotalCount.TotalClickNum)
	// 曝光量
	robotList, _, _ := dao.Robot{}.RobotList(ctx, db, "", "", "", salesID, "", "", "", "")
	var RobotNameList = []string{}
	for _, v := range robotList {
		if areas3 != "" {
			locationID := strconv.Itoa(v.Areas3)
			if lo.Contains(strings.Split(areas3, ","), locationID) {
				RobotNameList = append(RobotNameList, v.RobotName)
			}
		} else {
			RobotNameList = append(RobotNameList, v.RobotName)
		}
	}
	robotNames := strings.Join(RobotNameList, ",")
	faceCountTotal := dao.FaceCount{}.GetFaceCountTotal(ctx, dal.Q, merchantIDList, robotNames, StartTime, EndTime)
	TotalCount.TotalFaceCount = faceCountTotal.FaceCount

	field := "date_format(`add_time`, '" + DateFormate + "') AS date," +
		"COUNT(order_id) AS day_count_num," +
		"COUNT(order_id) AS day_pay_num," +
		"SUM(payment_amount) AS day_pay_amount"
		// "(SELECT 0) AS dis_count_amount"
		// "SUM(discount_amount) AS dis_count_amount"
	tx.WithContext(ctx).Select(field).
		Group("date").
		Order("date desc").
		Find(&Result)
	for k, v := range Result {
		if _, ok := DateDiscountOrderMap[v.Date]; ok {
			Result[k].DisCountAmount = DateDiscountOrderMap[v.Date].DiscountAmount
		}
		if _, ok := DateSuccessOrderMap[v.Date]; ok {
			Result[k].SuccessOrderCount = DateSuccessOrderMap[v.Date].SuccessOrderCount
			Result[k].SuccessOrderAmount = DateSuccessOrderMap[v.Date].PaymentAmount

		}
		if _, ok := DateNotPayOrderMap[v.Date]; ok {
			Result[k].NotPayOrderCount = DateNotPayOrderMap[v.Date].NotPayOrderCount
		}
		if _, ok := DateRefundOrderMap[v.Date]; ok {
			Result[k].RefundOrderCount = DateRefundOrderMap[v.Date].RefundOrderCount
			Result[k].RefundOrderAmount = DateRefundOrderMap[v.Date].RefundOrderAmount
		}
		if _, ok := DatePayNumMap[v.Date]; ok {
			Result[k].PayNum = DatePayNumMap[v.Date].PayNum
		}
		if _, ok := DateFaceCountMap[v.Date]; ok {
			Result[k].FaceCount = DateFaceCountMap[v.Date].FaceCount
		}
		if _, ok := DateClickNumMap[v.Date]; ok {
			Result[k].ClickNum = DateClickNumMap[v.Date].ClickNum
		}
		if dateType == define.WEEK {
			Result[k].YearWeek = common.GetWeekOfYearInt(v.Date)
		}
	}

	//FullTimeList 填充时间
	FullTimeList := common.GetPeriodsByType(StartTime, EndTime, dateType)
	var FullTimeResult = []CenterOrderStruct{}
	lang := carbon.NewLanguage()
	lang.SetLocale("zh-CN")
	var YearWeekDaysMap = make(map[int]struct {
		Max string
		Min string
	})
	for _, v := range FullTimeList {
		var dateRes = CenterOrderStruct{}
		for _, res := range Result {
			if v == res.Date {
				dateRes = res
				break
			}
		}
		dateRes.Date = v
		if dateType == define.WEEK {
			dateRes.Week = carbon.SetLanguage(lang).Parse(v).ToWeekString(carbon.PRC)
			dateRes.YearWeek = common.GetWeekOfYearInt(v)
			YearWeekDaysMap[dateRes.YearWeek] = SortWeekDays(YearWeekDaysMap[dateRes.YearWeek], v)
		}
		FullTimeResult = append(FullTimeResult, dateRes)
	}
	if dateType == define.WEEK {
		//周 => 数据统计
		var WeekResultMap = make(map[int]CenterOrderStruct)
		for _, v := range FullTimeResult {
			var item CenterOrderStruct
			if _, ok := WeekResultMap[v.YearWeek]; ok {
				item = WeekResultMap[v.YearWeek]
			}
			item.Date = YearWeekDaysMap[v.YearWeek].Min + "/" + YearWeekDaysMap[v.YearWeek].Max
			item.YearWeek = v.YearWeek
			item.DayCountNum += v.DayCountNum
			item.DayPayAmount += v.DayPayAmount
			item.DayPayNum += v.DayPayNum
			item.DisCountAmount += v.DisCountAmount
			item.SuccessOrderCount += v.SuccessOrderCount
			item.SuccessOrderAmount += v.SuccessOrderAmount
			item.RefundOrderCount += v.RefundOrderCount
			item.RefundOrderAmount += v.RefundOrderAmount
			item.NotPayOrderCount += v.NotPayOrderCount
			item.FaceCount += v.FaceCount
			WeekResultMap[v.YearWeek] = item
		}
		data = lo.MapToSlice(WeekResultMap, func(k int, v CenterOrderStruct) CenterOrderStruct {
			return v
		})
		sort.Slice(data, func(i, j int) bool {
			return data[i].YearWeek < data[j].YearWeek
		})
		return
	}
	sort.Slice(FullTimeResult, func(i, j int) bool {
		return FullTimeResult[i].Date < FullTimeResult[j].Date
	})
	return FullTimeResult, TotalCount, nil
}
